﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Web;

namespace CodeArt.SharePoint.SmartQuery
{
    /// <summary>
    /// <para>Various extension methods.</para>
    /// </summary>
    /// Sample of using ToCSV
    /// <example>
    /// DataTable table = dv.Table;
    /// // Assumes table is a DataTable
    /// string result = table.ToCSV(true);
    /// System.IO.File.WriteAllText(@"C:\sample.csv", result);
    /// System.Diagnostics.Process proc = new System.Diagnostics.Process();
    /// proc.StartInfo.FileName = @"C:\sample.csv";
    /// proc.StartInfo.UseShellExecute = true;
    /// proc.Start();
    /// </example>
    public static class Extensions
    {
        /// <summary>
        /// Converts the passed in data table to a CSV-style string.      
        /// </summary>
        /// <param name="table">Table to convert</param>
        /// <returns>Resulting CSV-style string</returns>
        public static string ToCSV(this DataTable table)
        {
            return ToCSV(table, ",", true);
        }

        public static void DownloadCsv(this HttpResponse response, DataTable dt)
        {

        }

        //直接输出到ResponseStream，避免中文编码问题
        //    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + str + ".csv");
        //    HttpContext.Current.Response.Charset = "UTF-8";
        //    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
        //    HttpContext.Current.Response.ContentType = "application/ms-excel";
        //    var dt = new DataTable();
        //    dt.ToCSVStream(HttpContext.Current.Response.OutputStream, true);
        public static Stream ToCSVStream(this DataTable table, Stream fs, bool includeHeader)
        {
            if (table == null)
                throw new ArgumentNullException("table");
            if (fs == null)
                throw new ArgumentNullException("fs");

            string delimiter = ",";
            //System.IO.MemoryStream fs = new System.IO.MemoryStream();
            StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8);

            if (includeHeader)
            {
                foreach (DataColumn column in table.Columns)
                {
                    sw.Write("\"");
                    sw.Write(column.ColumnName);
                    sw.Write("\"");
                    sw.Write(delimiter);
                }
                
                sw.Write(Environment.NewLine);
            }

            foreach (DataRow row in table.Rows)
            {
                foreach (object item in row.ItemArray)
                {
                    if (item is System.DBNull)
                        sw.Write(delimiter);
                    else
                    {
                        string itemAsString = item.ToString();
                        // Double up all embedded double quotes
                        itemAsString = itemAsString.Replace("\"", "\"\"");

                        // To keep things simple, always delimit with double-quotes
                        // so we don't have to determine in which cases they're necessary
                        // and which cases they're not.
                        itemAsString = "\"" + itemAsString + "\"";

                        sw.Write(itemAsString + delimiter);
                    }
                }
                sw.Write(Environment.NewLine);
            }
            sw.Close();
            return fs;
        }

       

        /// <summary>
        /// Converts the passed in data table to a CSV-style string.
        /// </summary>
        /// <param name="table">Table to convert</param>
        /// <param name="includeHeader">true - include headers<br/>
        /// false - do not include header column</param>
        /// <returns>Resulting CSV-style string</returns>
        public static string ToCSV(this DataTable table, bool includeHeader)
        {
            return ToCSV(table, ",", includeHeader);
        }

        /// <summary>
        /// Converts the passed in data table to a CSV-style string.
        /// </summary>
        /// <param name="table">Table to convert</param>
        /// <param name="delimiter">Delimiter used to separate fields</param>
        /// <param name="includeHeader">true - include headers<br/>
        /// false - do not include header column</param>
        /// <returns>Resulting CSV-style string</returns>
        public static string ToCSV(this DataTable table, string delimiter, bool includeHeader)
        {
            StringBuilder result = new StringBuilder();

            if (includeHeader)
            {
                foreach (DataColumn column in table.Columns)
                {
                    result.Append("\"");
                    result.Append(column.ColumnName);
                    result.Append("\"");
                    result.Append(delimiter);
                }

                result.Remove(--result.Length, 0);
                result.Append(Environment.NewLine);
            }

            foreach (DataRow row in table.Rows)
            {
                foreach (object item in row.ItemArray)
                {
                    if (item is System.DBNull)
                        result.Append(delimiter);
                    else
                    {
                        string itemAsString = item.ToString();
                        // Double up all embedded double quotes
                        itemAsString = itemAsString.Replace("\"", "\"\"");

                        // To keep things simple, always delimit with double-quotes
                        // so we don't have to determine in which cases they're necessary
                        // and which cases they're not.
                        itemAsString = "\"" + itemAsString + "\"";

                        result.Append(itemAsString + delimiter);
                    }
                }

                result.Remove(--result.Length, 0);
                result.Append(Environment.NewLine);
            }

            return result.ToString();
        }
    }
}
